import { isDevelopment, isH5 } from "./platform";
import { EncryptionToDecrypt } from "@/utils/aes";
import env from "@/config/env";
import { util } from "@/utils/util";
import Cheese, { Cheese as CHEESE } from "@/common/Cheese";

interface Params {
  [x: string]: string | number;
}

const getCommonParams = () => {
  let params: Params = {};

  return params;
};

const setOtherParams = () => {
  return {
    isLoading: true,
    hideLoading: true,
  }
}

const baseCatchInfo = (err: { errno: number; msg: string }, otherParams: any) => {
  const { msg = "加载中，稍候片刻！", errno = -1 } = err;
  switch (errno) {
    case 100:
    case 401:
      // todo 用于处理多次调用问题
      if (!uni.getStorageSync(CHEESE.Enum.STORE_KEY.LAPSE_TOKEN) && !otherParams?.notJump) {
        uni.setStorageSync(CHEESE.Enum.STORE_KEY.LAPSE_TOKEN, true);
        util.showDialogue(msg, 1000, () => Cheese.User!.loginOut());
      }
      break;
    default:
      util.showDialogue(msg);
      break;
  }
};

// h5环境开启代理
const apiBaseUrl = isH5 && isDevelopment ? "/v1" : env.apiBaseUrl;

const baseRequest = (
  method: "OPTIONS" | "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "TRACE" | "CONNECT" | undefined,
  url: string,
  data: object,
  otherParams?: any,
) => {
  return new Promise((resolve, reject) => {
    console.log(url, data);

    const isiOS = ["ios", "mac"].includes(uni.getSystemInfoSync().platform);
    if (otherParams.isLoading) {
      util.showLoading();
    }
    let header = {
      "content-type": method === "GET" ? "application/json; charset=utf-8" : "application/x-www-form-urlencoded",
      system: isiOS ? 0 : 1, // Android 1, Ios 0
      channel: "h5",
      version: "3.0.0",
      wxtoken: Cheese.User!.TOKEN,
      "xcx-version": CHEESE.version,
    }

    let responseData: any;
    uni.request({
      url: apiBaseUrl + url,
      method,
      timeout: 20000,
      header,
      data: {
        data: EncryptionToDecrypt.encryptionCryptoJS(JSON.stringify(data)),
      },
      success: (res: any) => {
        if (res.statusCode === 200 && (res.data.code === 200 || res.data.StatusCode === 200)) {
          responseData = res.data;
        } else {
          let params = {
            errno: res.data.code,
            msg: res.data.msg,
          }
          baseCatchInfo(params, otherParams);
          reject(params);
        }
      },
      fail: (e) => {
        util.hideLoading();
        baseCatchInfo({
          errno: -1,
          msg: "网络不给力，请检查你的网络设置~",
        }, otherParams);
        reject(e);
      },
      complete: () => {
        if (responseData) {
          if (responseData.isGz == 1) {
            const result = EncryptionToDecrypt.decryptionCryptoJS(responseData.data);
            resolve(result);

            console.log(JSON.stringify(result));
          } else if (responseData.StatusCode === 200) {
            resolve(responseData);
          } else {
            resolve(responseData.data);
          }
        }
        if (otherParams.hideLoading) {
          util.hideLoading();
        }
      },
    });
  });
};

const http = {
  get: <T>(api: string, params: any, otherParams?: any) =>
    baseRequest("GET", api, {
      ...getCommonParams(),
      ...params,
    }, {
      ...setOtherParams(),
      ...otherParams,
    }) as Http.Response<T>,
  post: <T>(api: string, params: any, otherParams?: any) =>
    baseRequest("POST", api, {
      ...getCommonParams(),
      ...params,
    }, {
      ...setOtherParams(),
      ...otherParams,
    }) as Http.Response<T>,
};

export default http;
